home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
smaltalk
/
st80_pr4.lha
/
st80_pre4
/
MoDE
/
EventTest-Shan.st
< prev
next >
Wrap
Text File
|
1993-07-24
|
18KB
|
647 lines
SharedQueue subclass: #EventQueue
instanceVariableNames: 'last putBack '
classVariableNames: 'Limit '
poolDictionaries: ''
category: 'EventTest-Shan'!
!EventQueue methodsFor: 'private'!
makeRoomAtEnd
"Don't let the contentsArray grow if the size is going to be larger
than the Limit. Instead throw away the events at front and write
to Transcript for warning."
"December 10, 1988 Shan"
| contentsSize |
"^super makeRoomAtEnd"
readPosition = 1
ifTrue: [contentsArray size < Limit
ifTrue: [contentsArray grow. ^false]
ifFalse:
[Transcript show: 'Event queue overflow\' withCRs.
readPosition _ 1.
writePosition _ 1.
readSynch initSignals. ^true
]]
ifFalse:
[contentsSize _ writePosition - readPosition.
1 to: contentsSize do: [:index | contentsArray at: index put: (contentsArray at: index + readPosition - 1)].
readPosition _ 1.
writePosition _ contentsSize + 1. ^false]! !
!EventQueue methodsFor: 'access'!
lastUpdatedCopy
"Returns the most recently arrieved event with the attributes
updated. Shan July 14, 1989"
| e |
last isNil ifTrue: [last _ MMSEvent new]. "Shan 25 May 1990"
e _ last copy.
"Store the previous point in extent for use of Enter/Leave events."
e previousOrigin: e origin.
"e origin: Sensor primMousePt.
^e setButtonStatus Shan 13 July 1990"
^ e!
next
"Inplement the put back function. When putBack is not nil. The event
pointed by putBack should be treated as the first event in the
queue. Shan 25 May 1990"
| temp |
putBack isNil
ifTrue: [^super next]
ifFalse:
[temp _ putBack.
putBack _ nil.
^temp]!
nextPut: value
"Handle the overflow case. Shan September 29, 1989"
| overflow |
overflow _ false.
accessProtect critical: [contents size > Limit
ifTrue:
["contents _ OrderedCollection new."
"Transcript show: 'Event queue overflow\' withCRs"
overflow _ true. "Shan 11 June 1990"
self init: contents size]
ifFalse: [contents addLast: value]].
last _ value deepCopy.
overflow ifFalse: [readSynch signal].
^value!
nextWithCursorMoveCompressed
"This is a message for tracing the cursor. If there are more than one
contineous cursorMove events in the queue, only the last one is
returned. Shan April 25, 1989"
"Compress the events"
| event |
[self size > 1]
whileTrue:
[event _ self next.
event selector == #cursorMove ifFalse: [^event]].
^self next!
peek
"Return an event if there is one in the queue. Otherwise, return nil.
The event is not removed from the queue. Shan 1 July 1990"
putBack isNil
ifTrue: [^super peek]
ifFalse: [^putBack]!
putBack: e
"Push back one event. This is only one level deep. Be VERY CAREFUL
when using this method. It may break the eventQ. Shan 25 May
1990"
putBack _ e!
size
"Shan 16 July 1990"
putBack isNil
ifTrue: [^super size]
ifFalse: [^super size + 1]! !
!EventQueue methodsFor: 'control'!
disable
"Ask the current InputState to stop generating events and flush self. This
way, there will be no event supply and the processes which read
from EventQ will be blocked."
InputState1 suspendGeneratingEvents.
self flush!
enable
InputState1 resumeGeneratingEvents!
flush
"Flushe the eventQ. All previous events are lost."
"Shan March 12, 1989"
self init: Limit! !
!EventQueue methodsFor: 'mouse'!
cursorPoint: aPoint
"Shan August 6, 1989"
| e |
Sensor cursorPoint: aPoint.
"self nextPut: (self lastUpdatedCopy selector: #cursorMove)."
"Change back for replay. Shan 8 July 1990"
last isNil ifTrue: [last _ MMSEvent new]. "Shan 25 May 1990"
e _ last copy. "Store the previous point in extent for use of Enter/Leave events."
e previousOrigin: e origin.
e origin: aPoint.
self nextPut: (e selector: #cursorMove)!
leftButtonDown
"Shan 19 July 1990"
^last leftButtonDown!
middleButtonDown
"Shan 19 July 1990"
^last middleButtonDown!
mousePoint
"'Sensor mousePoint' is not used for the purpose of replay. When
replaying a transcript, the cursorPosition will have no relationship at
all with the position of the recorded cursorPosition. Shan August 4,
1989"
"^last origin"
"This cause some problem when polling application is involved. The
last event only reflect the last mouse point before the cursor enters
a polling application. This problem came up when I tried to create a
hypertext link from the polling text editor. This also help the dragging
offset problem.Use the Sensor for the time being. Shan 25 May 1990"
"^Sensor mousePoint"
"Bring back the old one. Now I have an event-driven text editor.
Shan 8 July 1990"
^last origin!
rightButtonDown
"Shan 19 July 1990"
^last rightButtonDown!
waitButton
"Wait for the user to press any mouse button and then answer with
the current location of the cursor. Shan March 23, 1989"
| event selector |
[event _ self next.
selector _ event selector.
selector = #leftButtonDown | (selector = #rightButtonDown) | (selector = #middleButtonDown)] whileFalse.
^event origin!
waitClickButton
"Wait for the user to click (press and then release) any mouse button and then
answer with the current location of the cursor. Shan March 23, 1989"
self waitButton.
^self waitNoButton!
waitNoButton
"Wait for the user to release any mouse button and then answer with
the current location of the cursor. Shan August 22, 1989"
| event selector |
"self lastUpdatedCopy anyButtonDown ifFalse: [^last origin]." "Shan April 24, 1990"
last anyButtonDown ifFalse: [^last origin]. "Shan 13 July 1990"
[event _ self next.
selector _ event selector.
selector = #leftButtonUp | (selector = #rightButtonUp) | (selector = #middleButtonUp)] whileFalse.
^event origin! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
EventQueue class
instanceVariableNames: ''!
!EventQueue class methodsFor: 'initialize'!
initialize
Limit _ 100.
Smalltalk at: #EventQ put: (EventQueue new: Limit)! !
!EventQueue class methodsFor: 'event handling tests'!
buttonTest
"
Smalltalk at: #Consumer put: nil.
EventQ inspect.
Consumer inspect.
EventQueue initialize.
Consumer terminate.
| ee | Consumer _ [ [1=1] whileTrue: [ee _ EventQ next.
Transcript show: ee selector printString.
ee free] ] newProcess.
Consumer resume.
Consumer suspend.
"!
queueTest
"
Smalltalk at: #Consumer put: nil.
EventQ inspect.
Consumer inspect.
EventQueue initialize.
Consumer terminate.
| ee | Consumer _ [ [1=1] whileTrue: [ee _ EventQ next.
Transcript show: ee origin x printString.
ee free] ] newProcess.
Consumer resume.
| e | 13 timesRepeat: [e _ MMSEvent new.
Processor yield.
e origin: Sensor mousePoint.
EventQ nextPut: e].
Consumer suspend.
"! !
EventQueue initialize!
Object subclass: #MMSEvent
instanceVariableNames: 'origin previousOrigin msec buttonStatus keyboardEvent selector enterLeaveUsed data '
classVariableNames: ''
poolDictionaries: ''
category: 'EventTest-Shan'!
MMSEvent comment:
'The following is a list of event selectors. Shan November 30, 1989
1. cursorMove
2. leftButtonDown
middleButtonDown
rightButtonDown
3. leftButtonUp
middleButtonUp
rightButtonUp
4. leftButtonDoubleClick
middleButtonDoubleClick
rightButtonDoubleClick
5. keyboardEvent'!
!MMSEvent methodsFor: 'mouse buttons'!
anyButtonDown
"Shan August 1, 1989"
^buttonStatus > 0!
leftButtonDown
^(buttonStatus bitAnd: 4) ~= 0!
middleButtonDown
^(buttonStatus bitAnd: 2) ~= 0!
rightButtonDown
^(buttonStatus bitAnd: 1) ~= 0! !
!MMSEvent methodsFor: 'access'!
buttonStatus
"Shan August 1, 1989"
^buttonStatus!
buttonStatus: int
"Shan August 1, 1989"
buttonStatus _ int!
data
"Shan July 20, 1989"
^ data!
data: anObj
"data can be anything. Shan July 20, 1989"
data _ anObj!
keyboardEvent
^keyboardEvent!
keyboardEvent: aKeyboardEvent
keyboardEvent _aKeyboardEvent!
msec
"Shan February 12, 1990"
^msec!
msec: int
msec _ int!
origin
^origin!
origin: aPoint
origin _aPoint!
previousOrigin
^previousOrigin!
previousOrigin: aPoint
previousOrigin _aPoint!
selector
^selector!
selector: aSel
selector _ aSel! !
!MMSEvent methodsFor: 'initialize'!
initialize
origin _ Sensor mousePoint.
"The above statement is to prevent the first event after the 'EventQ
disable/enable to contain the wrong mouse point. Some times, the
mouse point is immediately queried after 'EventQ enable'. See
FixedImageLibObj>sizeByText. Shan September 6, 1989"
previousOrigin _ 0 @ 0.
msec _ 0.
buttonStatus _ 0.
selector _ 0.
enterLeaveUsed _ false! !
!MMSEvent methodsFor: 'free'!
free
self nilFields.! !
!MMSEvent methodsFor: 'private'!
enterLeaveUsed
"This is strictly private for the event dispatching mechanism to
process the enterLeave event. No other use allowed. It serves two
purposes. First for the correct process of the enterLeave events.
Second to optimize the computation of the process. Shan April 11,
1989 "
^enterLeaveUsed!
enterLeaveUsed: aBool
"This is strictly private for the event dispatching mechanism to
process the enterLeave event. No other use allowed. When
enterLeaveUsed is true. The modes should not use this cursorMove
event to generate any enterLeave events. A cursorMove event is
marked used after the first (topmost) mode has used it to process
the enterLeave events. Shan April 11, 1989"
enterLeaveUsed _ aBool! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
MMSEvent class
instanceVariableNames: ''!
!MMSEvent class methodsFor: 'instance creation'!
new
^super new initialize! !
InputState subclass: #InputState1
instanceVariableNames: ''
classVariableNames: 'ClosestLBtDownTime ClosestMBtDownTime ClosestRBtDownTime CursorTracingProcess GeneratingEvents SecondClosestLBtDownTime SecondClosestMBtDownTime SecondClosestRBtDownTime '
poolDictionaries: ''
category: 'EventTest-Shan'!
InputState1 comment:
'I am to replace the InputState class. The main purpose of me is to generate events'!
!InputState1 methodsFor: 'Event Generation'!
buttonDown: param
"Process only mouse button events."
"Dcember 11, 1988 Shan"
"Also set the time that the button is down."
"Shan March 16, 1989"
"Add in 'setButtonStatus' message here. It is tricky. May not be
consistent, but better than before. The 'buttonUp:' method is not
changed. More experiment needed to justify this. Shan May 15,
1989 "
| event |
GeneratingEvents
ifTrue:
[event _ EventQ lastUpdatedCopy.
event buttonStatus: Sensor buttons. "Shan 13 July 1990"
param = 130
ifTrue:
[event selector: #leftButtonDown.
EventQ nextPut: event.
SecondClosestLBtDownTime _ ClosestLBtDownTime.
ClosestLBtDownTime _ Time millisecondClockValue]
ifFalse: [param = 129
ifTrue:
[event selector: #middleButtonDown.
EventQ nextPut: event.
SecondClosestMBtDownTime _ ClosestMBtDownTime.
ClosestMBtDownTime _ Time millisecondClockValue]
ifFalse: [param = 128
ifTrue:
[event selector: #rightButtonDown.
EventQ nextPut: event.
SecondClosestRBtDownTime _ ClosestRBtDownTime.
ClosestRBtDownTime _ Time millisecondClockValue]]]]!
buttonUp: param
"Process only mouse button events."
"Dcember 11, 1988 Shan"
"Also generate the double click events."
"Shan March 16, 1989"
| event |
GeneratingEvents
ifTrue:
[event _ EventQ lastUpdatedCopy.
event buttonStatus: Sensor buttons. "Shan 13 July 1990"
param = 130
ifTrue:
[event selector: #leftButtonUp.
EventQ nextPut: event.
Time millisecondClockValue - SecondClosestLBtDownTime < 1000
ifTrue:
[event _ EventQ lastUpdatedCopy.
event selector: #leftButtonDoubleClick.
EventQ nextPut: event.
ClosestLBtDownTime _ 0.
SecondClosestLBtDownTime _ 0]]
ifFalse: [param = 129
ifTrue:
[event selector: #middleButtonUp.
EventQ nextPut: event.
Time millisecondClockValue - SecondClosestMBtDownTime < 1000
ifTrue:
[event _ EventQ lastUpdatedCopy.
event selector: #middleButtonDoubleClick.
EventQ nextPut: event.
ClosestMBtDownTime _ 0.
SecondClosestMBtDownTime _ 0]]
ifFalse: [param = 128
ifTrue:
[event selector: #rightButtonUp.
EventQ nextPut: event.
Time millisecondClockValue - SecondClosestRBtDownTime < 1000
ifTrue:
[event _ EventQ lastUpdatedCopy.
event selector: #rightButtonDoubleClick.
EventQ nextPut: event.
ClosestRBtDownTime _ 0.
SecondClosestRBtDownTime _ 0]]]]]!
cursorMove
| event |
GeneratingEvents
ifTrue:
[event _ EventQ lastUpdatedCopy.
event origin: Sensor primMousePt. "Shan 13 July 1990"
event origin = event previousOrigin ifTrue: [
"This is for the keyboard events. Smalltalk generates a
redundant cursorMove event before each key stroke
event. This is to eliminate that. Shan 3 July 1990"
^self]. "Store the previous point in extent for use of Enter/Leave
events."
event enterLeaveUsed: false.
event buttonStatus: Sensor buttons. "Shan 15 July 1990"
event selector: #cursorMove.
EventQ nextPut: event]!
generateKeyboardEvent: aKeyboardEvent upDown: int
"aKeyboardEvent is a Smalltalk KeyboardEvent. Package it to be a
MMSEvent."
"Shan March 11, 1989"
| event |
event _ EventQ lastUpdatedCopy.
event keyboardEvent: aKeyboardEvent.
int = 1
ifTrue: [event selector: #keyboardEvent]
ifFalse: ["This will never be generated because the keyboardUp event
in Smalltalk VM comes in pair with the keyboardDown event
event the user is holding the key down. There is no point
supporting this event. Shan June 7, 1989"
event selector: #keyboardUp].
^EventQ nextPut: event! !
!InputState1 methodsFor: 'private'!
keyAt: keyNumber put: value
| index mask keyboardEvent |
index _ keyNumber bitAnd: 255. "Get rid of meta bits"
(index < BitMin or: [index > OtherMeta3])
ifTrue: "Not a potential special character"
[value = 1 ifTrue: "only look at down strokes"
[index = InterruptKey
ifTrue: [(lshiftState ~= 0 or: [(keyNumber bitAnd: 16r100) ~= 0])
ifTrue: [self forkEmergencyEvaluatorAt: Processor userInterruptPriority]
ifFalse: [[ScheduledControllers interruptName: 'User Interrupt'] fork]]
ifFalse: [index = EmergencyInterruptKey
ifTrue: [self forkEmergencyEvaluatorAt: Processor userInterruptPriority]
ifFalse: [keyboardEvent _(KeyboardEvent
code: index
meta: (metaState bitOr: (keyNumber bitShift: -8))).
GeneratingEvents ifFalse: [^keyboardQueue nextPut: keyboardEvent]
ifTrue:[^self generateKeyboardEvent: keyboardEvent upDown: value]. ]]]]
ifFalse: [self setStateFor: index with: value.
metaState _ (((((ctrlState bitOr: (lshiftState bitOr: rshiftState)) bitOr: lockState) bitOr: metaKeyState)
bitOr: otherMetaKey1State) bitOr: otherMetaKey2State) bitOr: otherMetaKey3State]!
run
"This is the loop that actually processes input events. Shan September 29, 1989"
| word type param |
[true]
whileTrue:
[InputSemaphore wait.
"Test for mouse X/Y events here to avoid an activation."
word _ self primInputWord.
type _ word bitShift: -12.
param _ word bitAnd: 4095. "Transcript show: type printString."
"Mouse X" type = 1 ifTrue: [x _ param]
"Mouse Y" ifFalse: [type = 2 ifTrue: [y _ param. self cursorMove.]
"Key down" ifFalse: [type = 3 ifTrue: [self keyAt: param put: 1. self buttonDown: param]
"Key up" ifFalse: [type = 4 ifTrue: [self keyAt: param put: 0. self buttonUp: param]
"MetaInput"ifFalse: [type = 7 ifTrue: [self metaInput: word]
"Delta time"ifFalse: [type = 0 ifTrue: []
"Reset time"ifFalse: [type = 5 ifTrue: [self primInputWord; primInputWord]
ifFalse: [self error: 'Bad event type']]]]]]]]! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
InputState1 class
instanceVariableNames: ''!
!InputState1 class methodsFor: 'event generation control'!
resumeGeneratingEvents
GeneratingEvents _ true!
suspendGeneratingEvents
GeneratingEvents _ false! !
!InputState1 class methodsFor: 'initialize'!
initialize
"The CursorTracingProcess is a temperary hack due to the Smalltalk
2.3 cursorMove event compression. It should be removed when the
interpreter goes as specified in the document. The
'primSampleInterval:' method in InputState class is also tried but no
good."
"CursorTracingProcess terminate. CursorTracingProcess _ nil. InputState1 initialize"
"March 11, 1989 Shan"
| p p1 event delay |
self replaceSystemInputState. "Shan 5 August 1990"
"Setups for the generation of double click events."
"Shan March 16, 1989"
ClosestLBtDownTime _ 0.
SecondClosestLBtDownTime _0.
ClosestMBtDownTime _ 0.
SecondClosestMBtDownTime _0.
ClosestRBtDownTime _ 0.
SecondClosestRBtDownTime _0.
GeneratingEvents _ false.
(Smalltalk version = 'Smalltalk-80, Version 2.3 of 13 June 1988' and: [CursorTracingProcess == nil])
ifTrue:
["This is version 2.3"
delay _ (Delay forMilliseconds: 100).
CursorTracingProcess _ [[true]
whileTrue:
[p _ Sensor mousePoint.
(GeneratingEvents and: [p ~= p1])
ifTrue:
[event _ EventQ lastUpdatedCopy.
event selector: #cursorMove.
EventQ nextPut: event.
p1 _ p].
delay wait]] newProcess.
CursorTracingProcess priority: Processor lowIOPriority.
"When we can make sure the supends and resumes paired up,
this should be controlled by the same mechanism that
controls the GeneratingEvents. The process should not
running all the time."
CursorTracingProcess resume]! !
!InputState1 class methodsFor: 'become real'!
replaceSystemInputState
"InputState1 replaceSystemInputState"
InputSensor install! !
InputState1 initialize!